﻿using System;
using System.Linq;

using MSAcademic.v2.Database;
using MSAcademic.v2.Infrastructure.User;
using MSAcademic.v2.Infrastructure.Utility;

namespace MSAcademic.v2.Infrastructure.PasswordRecovery.Impl
{
    public partial class DatabasePasswordRecoveryService : IPasswordRecoveryService
    {
        public string GenerateToken(string username)
        {
            using (var db = new MSAcademicDatabaseContainer())
            {
                var token = new PasswordResetToken
                {
                    TokenValue = _nonceGenerator.GetNewWithoutSpecialChars(32),
                    CreatedOn = DateTime.Now,
                    UserId = _userQueries.TryGetWhereUsername(username).Id
                };

                db.PasswordResetTokens.Add(token);
                db.SaveChanges();

                return token.TokenValue;
            }
        }

        public bool VerifyToken(string tokenValue)
        {
            using (var db = new MSAcademicDatabaseContainer())
            {
                var token = (from t in db.PasswordResetTokens
                             where t.TokenValue == tokenValue
                             select t).SingleOrDefault();

                if (token == null)
                {
                    return false;
                }

                return (token.UsedOn == null) && (token.CreatedOn.AddDays(3) >= DateTime.Now);
            }
        }

        public void MarkTokenAsUsed(string tokenValue)
        {
            using (var db = new MSAcademicDatabaseContainer())
            {
                var token = (from t in db.PasswordResetTokens
                             where t.TokenValue == tokenValue
                             select t).SingleOrDefault();

                if (token != null)
                {
                    token.UsedOn = DateTime.Now;
                }

                db.SaveChanges();
            }
        }

        public int TryGetUserIdWhereToken(string tokenValue)
        {
            using (var db = new MSAcademicDatabaseContainer())
            {
                var token = (from t in db.PasswordResetTokens
                             where t.TokenValue == tokenValue
                             select t).SingleOrDefault();

                return token != null
                       ? token.UserId
                       : -1;
            }
        }
    }

    public partial class DatabasePasswordRecoveryService
    {
        private readonly RandomNonceGenerator _nonceGenerator;
        private readonly IUserQueries _userQueries;

        public DatabasePasswordRecoveryService(
            RandomNonceGenerator nonceGenerator,

            IUserQueries userQueries)
        {
            _nonceGenerator = nonceGenerator;
            _userQueries = userQueries;
        }
    }
}
